﻿using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Abp.Domain.Entities;
using Abp.Domain.Repositories;
using Abp.Domain.Services;
using KelonProud.Extensions;

namespace KelonProud.Linq
{
    public abstract class KelonProudDomainService<T> : KelonProudDomainService<T, int> where T : class, IEntity<int>
    {
        protected KelonProudDomainService(IRepository<T, int> manageRepository) : base(manageRepository)
        {
        }
    }

    public abstract class KelonProudDomainService<T, TPrimaryKey> : DomainService where T : class, IEntity<TPrimaryKey>
    {
        protected  readonly IRepository<T, TPrimaryKey> ManagerRepository;

        protected KelonProudDomainService(IRepository<T, TPrimaryKey> manageRepository)
        {
            ManagerRepository = manageRepository;
        }

        public virtual T GetById(TPrimaryKey id)
        {
            return ManagerRepository.FirstOrDefault(f=>Equals(f.Id, id));
        }


        public virtual Task<T> GetByIdtAsync(TPrimaryKey id)
        {
            return ManagerRepository.FirstOrDefaultAsync(f => Equals(f.Id, id));
        }

        public virtual TPrimaryKey SaveGetId(T t)
        {
            VerifySaveOrUpdateError(t);

            return ManagerRepository.InsertOrUpdateAndGetId(t);
        }

        public virtual Task<TPrimaryKey> SaveGetIdAsync(T t)
        {
            VerifySaveOrUpdateError(t);

            return ManagerRepository.InsertOrUpdateAndGetIdAsync(t);
        }

        public virtual T Save(T t)
        {
            VerifySaveOrUpdateError(t);

            return ManagerRepository.InsertOrUpdate(t);
        }

        public virtual Task<T> SaveAsync(T t)
        {
            VerifySaveOrUpdateError(t);

            return ManagerRepository.InsertOrUpdateAsync(t);
        }

        public virtual void Delete(TPrimaryKey id)
        {
            var dom = GetById(id);

            if(dom!=null)
                ManagerRepository.Delete(dom);
        }

        protected virtual void VerifySaveOrUpdateError(T t)
        {
        }

        public IAbpSessionExtension AbpSession { get; set; }

        public virtual IQueryable<T> Query => ManagerRepository.GetAll();

        public virtual List<T> List => ManagerRepository.GetAllList();

        public virtual Task<List<T>> ListAsync => ManagerRepository.GetAllListAsync();
    } 
}
